<?php

/*
@版本日期: 2010年5月30日
@著作权所有: Lou Barnes ( http://www.loubarnes.com )

获得使用本类库的许可, 您必须保留著作权声明信息.
报告漏洞，意见或建议, 请联系 Lou Barnes(iua1024@gmail.com) 或登陆 http://www.loubarnes.com
*/

class library_mail extends library
{
	private $from_mail = null;		// 发件邮箱
	private $from_name = null;		// 发件人
	private $reply_to = null;			// 接收回复邮箱
	private $to = array();			// 收件邮箱
	private $attachments = array();	// 附件

	private $subject = '';					// 邮件主题
	private $body = '';						// 邮件内容
	private $content_type = 'text/html';		// 邮件类型
	private $charset = "utf-8";				// 字符集

	private $smtp = null;	// smtp 信息

	// 构造函数
	public function __construct()
	{
		$config = bone::get_config('mail');

		if($config->from_mail) $this->from_mail = $config->from_mail;
		if($config->from_name) $this->from_name = $config->from_name;
		if($config->charset) $this->charset = $config->charset;
		if($config->encoding) $this->encoding = $config->encoding;
		
		if($config->smtp)
		{
			$this->set_smtp($config->smtp, $config->smtp_host, $config->smtp_user, $config->smtp_pass, $config->smtp_port, $config->smtp_ssl, $config->smtp_timeout);
		}
	}
	

	// 析构函数
	public function __destruct()
	{
	}

	public function set_from($from_mail, $from_name = null)
	{
		$this->from_mail = $from_mail;
		if($from_name)
			$this->from_name = $from_name;
		else
			$this->from_name = $from_mail;
	}

	public function set_smtp($enable, $host, $user = null, $pass = null, $port=25, $ssl = false, $timeout = 30 )
	{
		if($enable)
		{
			if(!$this->smtp) $this->smtp = new stdClass();
			$this->smtp->host = $host;				// smtp 主机地址
			$this->smtp->user = $user;				// smtp 用户名
			$this->smtp->pass = $pass;				// smtp 用户密码
			$this->smtp->port = $port;				// smtp 主机端口
			$this->smtp->ssl = $ssl;					// smtp 用户密码
			$this->smtp->timeout = $timeout;			// smtp 超时时间秒
		}
		else
		{
			$this->smtp = null;
		}
	}

	
	// 添加收件人
	public function to($email = null)
	{
		if($this->verify($email))
		{
			$this->to[] = $email;
		}
		else
		{
			$this->error = '邮箱('.$email.')格式非法';
			return false;
		}

		return true;
	}

	public function add_attachment($path = null)
	{
		// 暂未开发
		return;
	}

	public function set_subject($sSubject = '')
	{
		$this->subject = $sSubject;
	}

	public function set_body($body = '')
	{
		$this->body = $body;
	}

	// 设置邮件内容是否显示为 HTMl 格式
	public function is_html($b = true)
	{
		if($b)
		{
			$this->content_type = 'text/html';
		}
		else
		{
			$this->content_type = 'text/plain';
		}
	}


	public function send()
	{
		if( !count($this->to) )
		{
			$this->error = '未设置收件邮箱';
			return false;
		}

		if($this->smtp)
		{
			return $this->smtp_send();
		}
		else
		{
			return mail(implode(", ", $this->to), $this->subject, $this->body, $this->create_header());
		}
	}

	public function smtp_send()
	{
		$socket = fsockopen($this->smtp->host, $this->smtp->port, $err_no, $err_msg, $this->smtp->timeout);
		if(!$socket)
		{
			$this->error = '连接smtp主机('.$this->smtp->host.')失败: '.$err_no.' - '.$err_msg;
			return false;
		}

		if(substr(PHP_OS, 0, 3) != "WIN")
			socket_set_timeout($socket, $this->smtp->timeout, 0);


		fputs($socket, 'HELO MrBone'."\r\n");
		$line = trim(fgets($socket, 515));

        if($this->smtp->user)
        {
			fputs($socket, "AUTH LOGIN\r\n");
			$line = trim(fgets($socket, 515));
			fputs($socket, base64_encode($this->smtp->user)."\r\n");
			$line = trim(fgets($socket, 515));
			fputs($socket, base64_encode($this->smtp->pass)."\r\n");
			$line = trim(fgets($socket, 515));
			$line = trim(fgets($socket, 515));
			$code = substr($line,0,3);
			if($code != 235)
			{
				$this->error = 'smtp 用户名和密码验证错误: '.$line;
				return false;
			}
        }
		fputs($socket, 'MAIL FROM:<'.$this->from_mail.">\r\n");
		$line = trim(fgets($socket, 515));

        $to = $this->to;
        foreach($to as $email)
        {
			fputs($socket, 'RCPT TO:<' . $email . ">\r\n");
			$line = trim(fgets($socket, 515));
        }
        fputs($socket,"DATA\r\n");
		$line = trim(fgets($socket, 515));

		$data = $this->create_header();
		$data .= $this->create_body();

		fputs($socket,	$data);
		
		$line = trim(fgets($socket, 515));
		$code = substr($line,0,3);
		if($code != 250)
		{
			$this->error = '发送邮件失败: '.$line;
			return false;
		}

		fputs($socket, "QUIT\r\n");
        return true;
	}
	
	public function reset()
	{
		$this->to = array();
		$this->attachments = array();
	}


	private function create_header()
	{
		$data = 'From: =?'.$this->charset.'?B?'.base64_encode($this->from_name).'?= <'.$this->from_mail.">\r\n";
		$data .= 'Reply-To: '.$this->from_name.' <'.$this->from_mail.">\r\n";
		$data .= 'To: '.implode(",", $this->to)."\r\n";
		$data .= 'Subject: =?'.$this->charset.'?B?'.base64_encode($this->subject)."?=\r\n";
		$data .= 'Message-ID: <'.time().'.'.$this->from_mail.">\r\n";
		$data .= 'Date: '.date('r')."\r\n";
		$data .= "X-Priority: 3\r\n";
		$data .= "X-Mailer: Mr Bone\r\n";
		$data .= "Copyright: www.mrbone.org\r\n";
		$data .= "MIME-Version: 1.0\r\n";
		$data .= 'Content-Type: '.$this->content_type.'; charset="' . $this->charset . "\"\r\n\r\n";

		return $data;
	}
	
	private function create_body()
	{
		$data = $this->body. "\r\n.\r\n";
		return $data;
	}

	public function verify($email)
	{
		return preg_match("/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/i", $email);
	}


}
